const createError = require('http-errors');
const express = require('express');
const path = require('node:path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const compression = require('compression');
const cors = require('cors');
const history = require('connect-history-api-fallback');
const { createServer } = require("http");
const { Server } = require("socket.io");
const process = require('process');
const app = express();
const debug = require('debug')('bwg-server:server');
const { expressjwt: jwt } = require('express-jwt')

const indexRouter = require('./routes/index');
const articlesRouter = require('./routes/articles');
const columnsRouter = require('./routes/columns')
const userRouter = require('./routes/user');
const followigRouter = require('./routes/followig');
const editRouter = require('./routes/edit')
const workBench = require('./routes/work')
const socketRouter = require('./routes/message');
// const { createProxyMiddleware } = require('http-proxy-middleware');
const port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
const server = createServer(app);

const corsOrigin = process.env.BASE_CORS
const io = new Server(server, {
  cors: {
     origin: corsOrigin, // 允许所有域名，或者指定允许的域名列表
     methods: ["GET", "POST"],
     allowedHeaders: ["my-custom-header"],
     credentials: true
  }
 });

server.listen(port, () => {
  console.log('ok');
});
server.on('error', onError);
server.on('listening', onListening);
function normalizePort(val) {
  const port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  const bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

function onListening() {
  const addr = server.address();
  const bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}



const secret = process.env.JWT_SECRET;
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
 
// app.use(compression())
// app.use(helmet())
app.use(history());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(cors({
  origin: corsOrigin, // 允许的源
  methods: ['GET', 'POST'], // 允许的HTTP方法
  allowedHeaders: ['Content-Type', 'Authorization'], // 允许的请求头
  credentials: true
}))

// 假设你的API服务运行在 localhost:5000 上
const request = require('request');
app.use('/api', (req, res) => {
  const url = `${process.env.BASE_URL}${req.path}`;
  req.pipe(request(url)).pipe(res);
});

// JWT 验证中间件
const jwtMiddleware = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) {
    return res.status(401).send('Access Denied');
  }
  try {
    const verified = jwt.verify(token, secret);
    req.user = verified;
    next();
  } catch (err) {
    res.status(400).send('无效的身份');
  }
};

// 使用 JWT 验证中间件的路由
app.get('/protected', jwtMiddleware, (req, res) => {
  res.send('Protected Route');
});


const handleSocketConnection = require('./routes/socket'); 
const jwtWeb = require('jsonwebtoken');
const acceptIdToSocketIdMap = {};
io.on('connection', (socket) => {
  // 验证 token
  const auth = socket.handshake.auth;
  const token = auth.token?.split(' ')[1];
  jwtWeb.verify(token, secret, (err, decoded) => {
    if (err) {
      socket.emit('authError', {status: -1, data: {msg: '断开连接'}})
      socket.disconnect();
    } else {
      // 通过身份验证建立连接
      const {id, username} = decoded
      acceptIdToSocketIdMap[id] = socket.id
      socket.emit('authSuccess', {status: 200, data: {msg: '连接到socket'}})
      handleSocketConnection(socket, acceptIdToSocketIdMap)
    }
  });
});



app.use('/', indexRouter)
app.use('/user', userRouter)
app.use('/article', articlesRouter)
app.use('/column', columnsRouter)
app.use('/followig', followigRouter)
app.use('/edit', editRouter)
app.use('/work', workBench)
app.use('/msg', socketRouter)

// catch 404 and forward to error handler
app.use('/*', function (req, res, next) {
  // 未匹配
  // res.redirect('/')
});

// 错误处理 handler
app.use((err, req, res, next) => {
  if (err.name === "UnauthorizedError") {
    res.status(401).send({ msg: "无有效身份，请重新登录" });
  } else {
    console.error(err.stack);
    res.status(500).send({ msg: res.message })
  }

});



module.exports = app;
